package com.cratos.xxgram.platf.group;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.service.RetResult;
import org.redkale.source.ColumnValue;
import org.redkale.source.FilterExpress;
import org.redkale.source.FilterFunc;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.AnyValue;
import org.redkale.util.Comment;
import org.redkale.util.Sheet;
import org.redkale.util.Utility;

import com.cratos.xxgram.platf.base.BaseService;
import com.cratos.xxgram.platf.base.RetCodes;
import com.cratos.xxgram.platf.base.UserInfo;
import com.cratos.xxgram.platf.message.BasicContent;
import com.cratos.xxgram.platf.message.MessageRecord;
import com.cratos.xxgram.platf.message.MessageService;
import com.cratos.xxgram.platf.message.NotifyContent.DissMissGroupNotify;
import com.cratos.xxgram.platf.util.QueueTask;
import com.cratos.xxgram.platf.message.NotifyHandler;

/**
 *
 * @author SquRab
 */
@RestService(name = "group", comment = "群组服务")
public class GroupServiceWs extends BaseService {

	@Comment("异步执行")
	public final QueueTask<Runnable> ansyQueue = new QueueTask<>(1);
	 
	@Resource
	private MessageService messageService;
	
	@Override
	public void init(AnyValue config) {
		ansyQueue.init(logger, task -> task.run());
	}
	
	@Override
	public void destroy(AnyValue config) {
		ansyQueue.destroy();
	}
	
    @RestMapping(name = "updateSystemSetting", auth = true, comment = "更群和以及个人配置")
    public RetResult updateSystemSetting(UserInfo userInfo, int groupid, int index, int value) {
        String usergroupId = groupid + "-" + userInfo.getUserid();
        UserGroup userGroup = source.find(UserGroup.class, usergroupId);
        GroupDetail groupDetail = source.find(GroupDetail.class, groupid);
        if (userGroup == null || groupDetail == null) {
            return RetCodes.retResult(RetCodes.RET_RONGCLOUD_UPDATE_GROUP_ERROR);
        }
        // 群组权限 只有群组才能禁言 设置匿名群
        if (index <= UserGroup.SYSSETTING_GROUP_LIMIT_INDEX) {
        	// 校验是不是管理员
            if (groupDetail.getCreateuserid() != userInfo.getUserid()) {
                return RetCodes.retResult(RetCodes.RET_RONGCLOUD_GROUP_INVALID_PERMISSION);
            }
            long oldVal = groupDetail.getSyssetting();
            long decVal = (long) Math.pow(2, (index -1));
            long yuVal = 0xFFFFFFFF - decVal;
            long cValue = yuVal & oldVal;//减少  当前位的值  获得其他位数的值
            // 判断当前位数的值是否需要增加
            if (value == 1) {
                cValue = cValue + decVal;
            }
            //更新群信息
            source.updateColumnAsync(GroupDetail.class, groupDetail.getGroupid(), ColumnValue.mov("syssetting", cValue)).whenComplete((o, r) -> {
                if (r == null) {
                    source.queryListAsync(UserGroup.class, FilterNode.create("groupid", FilterExpress.EQUAL, groupid)).whenComplete((dataList, error) -> {
                        if (error != null) {
                            logger.finest("updateSystemSetting error ....." + error.getMessage());
                            return;
                        }
                        dataList.forEach(obj -> updateSystemSetting(obj.getUserid(), obj.getGroupid(), index, value));
                    });
                }
            }).join();
        }
        // 更新自己的配置
        return updateSystemSetting(userInfo.getUserid(), groupid, index, value);
    }

    @Comment("更新群状态")
    private RetResult updateSystemSetting(int userId, int groupId, int index, int value) {
        String usergroupId = groupId + "-" + userId;
        UserGroup userGroup = source.find(UserGroup.class, usergroupId);
        if (userGroup == null) {
            return RetCodes.retResult(RetCodes.RET_FRIENDSHI_FRIENDINFO_NOTEXIT_FIRIND);
        }
        long oldVal = userGroup.getSyssetting();
        //  long decVal = ((index - 1) == 0) ? 1 : (index - 1) << 2;
        index = (index - 1);
        long decVal = (long) Math.pow(2, index);
        long yuVal = 0xFFFFFFFF - decVal;
        long cValue = yuVal & oldVal;//减少  当前位的值  获得其他位数的值
        // 判断当前位数的值是否需要增加
        if (value == 1) {
            cValue = cValue + decVal;
        }
        source.updateColumn(UserGroup.class, usergroupId, ColumnValue.mov("syssetting", cValue));
        //更新字段值
        return RetResult.success(cValue);
    }

    @Comment("修改聊天背景")
    public RetResult updateChatBackGround(UserGroup bean) {
        source.updateColumn(UserGroup.class, bean.getUsergroupid(), "chatbackground", bean.getChatbackground());
        return RetResult.success();
    }

    @Comment("更新用户群昵称")
     @RestMapping(name = "updateUserGroupName", auth = true, comment = "更新用户群昵称")
    public RetResult updateUserGroupName(UserInfo userInfo, UserGroup bean) {
        int groupId = bean.getGroupid();
        int userId = userInfo.getUserid();
        bean.setUsergroupid(groupId + "-" + userId);
        bean.setUsernickname(bean.getUsernickname());
        source.updateColumn(bean, "usernickname");
        return RetResult.success(source.updateColumn(bean, "usernickname"));
    }



    @RestMapping(name = "queryGroupList", auth = true, comment = "查询群列表")
    public RetResult queryGroupList(UserInfo userInfo) {
        // 查询当前用户所在的所以群
        List<GroupDetail> queryList = new java.util.ArrayList();
        Sheet<UserGroup> sheet = source.querySheet(UserGroup.class, null, FilterNode.create("userid", FilterExpress.EQUAL, userInfo.getUserid()));
        Collection<UserGroup> rows = sheet.getRows();
        if (rows != null && rows.size() > 0) {
            List<Integer> groupids = rows.stream().map(o -> o.getGroupid()).collect(Collectors.toList());
            GroupDetailBean bean = new GroupDetailBean();
            bean.setGroupid(groupids.stream().toArray(Integer[]::new));
            queryList = source.queryList(GroupDetail.class, bean);
            queryList.forEach(obj -> {
                obj.setCreator(source.find(UserInfo.class, obj.getCreateuserid()));
            });
        }
        return RetResult.success(queryList);
    }

    @RestMapping(name = "queryGroupMember", auth = true, comment = "查询群组成员")
    public RetResult queryGroupMember(UserInfo userInfo, int groupId) {
        GroupDetail groupDetail = source.find(GroupDetail.class, groupId);
        Flipper sortFlipper = new Flipper(1000, "jointime asc");//群最大成员1000
        List<UserGroup> userGroups = source.queryList(UserGroup.class, sortFlipper, FilterNode.create("groupid", FilterExpress.EQUAL, groupId));
          UserGroup userGroup = source.find(UserGroup.class, FilterNode
                    .create("groupid", FilterExpress.EQUAL, groupId)
                    .and("userid", FilterExpress.EQUAL, userInfo.getUserid()));
          Number numberResult = source.getNumberResult(UserGroup.class, FilterFunc.COUNT, "groupid", FilterNode.create("groupid", FilterExpress.EQUAL, groupId));
          int usernum = numberResult.intValue();
        if(userGroup != null) {
            groupDetail.setSyssetting(groupDetail.getSyssetting() | userGroup.getSyssetting()); //群配置取或运算
            groupDetail.setUsernum(usernum);
            groupDetail.setCreator(source.find(UserInfo.class, groupDetail.getCreateuserid()));
        }
        Map<String, Object> resultMap = new HashMap();
        resultMap.put("groupDetail", groupDetail);
        resultMap.put("userGroups", userGroups);
        return RetResult.success(resultMap);
    }
    
    @RestMapping(name = "queryGroupUserDetail", auth = true, comment = "查询群成员详情")
    public RetResult queryGroupUserDetail(int userid, int groupId) {
        GroupDetail groupDetail = source.find(GroupDetail.class, groupId);
        if (groupDetail == null) return RetCodes.retResult(RetCodes.RET_RONGCLOUD_USER_NOTIN_GROUP);
        UserGroup userGroup = source.find(UserGroup.class, FilterNode
                    .create("groupid", FilterExpress.EQUAL, groupId)
                    .and("userid", FilterExpress.EQUAL, userid));
        if(userGroup != null) {
        	userGroup.setSyssetting(groupDetail.getSyssetting() | userGroup.getSyssetting());
        }
        return RetResult.success(userGroup);
    }
    
    
    
    @RestMapping(name = "updateChatBackGround", auth = true, comment = "修改聊天背景")
    public RetResult updateChatBackGround(UserInfo userInfo, UserGroup bean) {
        source.updateColumn(UserGroup.class, bean.getUsergroupid(), "chatbackground", bean.getChatbackground());
        return RetResult.success();
    }
    
    @RestMapping(name = "queryGroupInfo", auth = true, comment = "查询群详情")
    public RetResult queryGroupInfo(UserInfo userInfo, int groupId) {
        GroupDetail groupDetail = source.find(GroupDetail.class, groupId);
        if (groupDetail == null) return RetCodes.retResult(RetCodes.RET_GROUP_UNEXIST);
        Number numberResult = source.getNumberResult(UserGroup.class, FilterFunc.COUNT, "groupid", FilterNode.create("groupid", FilterExpress.EQUAL, groupId));
        int intValue = numberResult.intValue();
        UserGroup userGroup = source.find(UserGroup.class, FilterNode
                    .create("groupid", FilterExpress.EQUAL, groupId)
                    .and("userid", FilterExpress.EQUAL, userInfo.getUserid()));
        if(userGroup != null) {
            groupDetail.setSyssetting(groupDetail.getSyssetting() | userGroup.getSyssetting()); //群配置取或运算
            groupDetail.setChatbackground(userGroup.getChatbackground()); //聊天背景图片
            groupDetail.setUsernum(intValue);
        }
        return RetResult.success(groupDetail);
    } 
    
    public RetResult dismissGroup(int groupId) {
    	 DissMissGroupNotify content = new DissMissGroupNotify();
    	 content.setGroupId(groupId);
         GroupDetail group = source.find(GroupDetail.class,
                 FilterNode.create("groupid", FilterExpress.EQUAL, content.getGroupId()));
         if (group == null) {
        	 return RetCodes.retResult(RetCodes.RET_GROUP_UNEXIST);
         }
         
         // 解散群通知
         BasicContent.TipMessage tipMessage = new BasicContent.TipMessage();
         tipMessage.setType(BasicContent.TipMessage.GROUP_DISMISSGROUP_TP);
         tipMessage.setExtra(group);
         tipMessage.setContent("群已解散!!!");
         {
             long now = System.currentTimeMillis();
             MessageRecord tipRecord = new MessageRecord();
             tipRecord.setMsgtype(BasicContent.TipMessage.TYPE);
             tipRecord.setFromid(UserInfo.USERID_SYSTEM);
             tipRecord.setTargetid(content.getGroupId());
             tipRecord.setContent(JsonConvert.root().convertTo(tipMessage));
             tipRecord.setMsgkind(MessageRecord.MSG_KIND_GROUP);// 群发
             tipRecord.setMessageid(
            		 groupId + "-" + UserInfo.USERID_SYSTEM + "-" + Utility.format36time(now));
             tipRecord.setCreatetime(now);
             tipRecord.setTargetid(content.getGroupId());
             // 同步发送群发给 被拉进群的用户
             List<UserGroup> receiverUsers = source.queryList(UserGroup.class, FilterNode.create("groupid", FilterExpress.EQUAL, group.getGroupid()));
             logger.finest("rec grouduser " + JsonConvert.root().convertTo(receiverUsers));
             // 处理解散群业务逻辑
            try {
            	messageService.sendMessage(tipRecord);
			} catch (Exception e) {
				e.printStackTrace();
			} 
             receiverUsers.forEach((ug) -> {
            	 source.insertAsync(ug.createTableHis(now));
             });
             source.insertAsync(group.createTableHis(now));
             source.delete(UserGroup.class, FilterNode.create("groupid", FilterExpress.EQUAL, groupId)); // 清除群记录
             source.delete(GroupDetail.class, groupId); // 删除群信息
         }
     
        return RetResult.success();
    }
    
    
    @Comment("踢除群组")
    public RetResult removeUserFromGroup(UserInfo userInfo, int groupId) {
        GroupDetail groupDetail = source.find(GroupDetail.class, groupId);
        UserGroup userGroup = source.find(UserGroup.class, FilterNode
                .create("groupid", FilterExpress.EQUAL, groupId)
                .and("userid", FilterExpress.EQUAL, userInfo.getUserid()));
        // 群不存在
        if (groupDetail == null) {
            return RetCodes.retResult(RetCodes.RET_GROUP_UNEXIST);
        }
        // 用户不再群组中
        if (userGroup == null)  {
        	return RetCodes.retResult(RetCodes.RET_RONGCLOUD_USER_NOTIN_GROUP);
        }
        // 记录历史表
        source.insert(userGroup.createTableHis(System.currentTimeMillis()));
        return RetResult.success(source.delete(userGroup));
    }
    
    /**
     * 更新用户所在群的群头像
     * @param userid
     * @return
     */
    public CompletableFuture<Integer> updateGroupFace(String face ,int userid) {
    	// 更新用户所在群头像
    	ansyQueue.add(() -> {
    		logger.finest("ansyQueue start exec .......");
    		source.updateColumn(UserGroup.class, FilterNode.create("userid", FilterExpress.EQUAL, userid), ColumnValue.mov("face", face));
    		try {
            	source.queryListAsync(UserGroup.class, FilterNode.create("userid", FilterExpress.EQUAL,  userid)).whenComplete((rows, error) -> {
            		if (error != null) {
            			logger.finest("update face error " + error.getMessage());
            		} else {
            			rows.forEach((usergroup) -> {
            				int groupid = usergroup.getGroupid();
            				Integer userId = usergroup.getUserid();
            				Flipper flipper = new Flipper(9, "jointime desc");
            				List<Integer> userids = source.queryColumnList("userid",UserGroup.class, flipper, FilterNode.create("groupid", FilterExpress.EQUAL,  groupid));
            				// 如果排在前9个 就更新头像
            				if(userids.contains(userId)) {
            					GroupDetail detail = new GroupDetail();
            					detail.setGroupid(groupid);
            					updateGroupFace(detail);
            					
            				}
            			});
            		}
            	}).join();
            	logger.finest("userid = " + userid +"face =" + face + " face update success !!!");
        	} catch (Exception e) {
    			e.printStackTrace();
    			logger.finest("userid = " + userid +"face =" + face + " face update error !!!");
    		}
    		logger.finest("ansyQueue end exec .......");
    	});
    	return CompletableFuture.completedFuture(0);
    }
    
    @Comment("更新群头像")
    protected void updateGroupFace(GroupDetail bean)  {
    	 try {
    		 long now = System.currentTimeMillis();
    		 logger.finest("updateGroupFace start ....");
             Flipper flipper = new Flipper(9, "jointime desc");
             List<String> userfaces = source.queryColumnList("face", UserGroup.class, flipper, FilterNode.create("groupid", FilterExpress.EQUAL, bean.getGroupid()));
             String groupface = fileService.storeGroupImage(Integer.toString(bean.getGroupid(), 36) + "-" + Long.toString(now, 36), userfaces);
             bean.setGroupface(groupface);
             bean.setInfotime(now);// 更新时间
             source.updateColumn(bean, "groupface","infotime");// 更新群头像
             logger.finest("updateGroupFace end ....");
         } catch (IOException ex) {
             Logger.getLogger(NotifyHandler.class.getName()).log(Level.SEVERE, null, ex);
         }
    }
    
    public static void main(String[] args) throws Exception {
    	GroupServiceWs groupServiceWs = org.redkale.boot.Application.singleton(GroupServiceWs.class);
    	groupServiceWs.updateGroupFace("XX", 300000005);
    	Thread.sleep(1 * 20);
	}
}
